<template>
  <div class="form-common-list-div">
    <el-form
      :model="detail_data"
      :label-width="labelWidth"
      :label-position="labelPosition"
    >
      <el-row>
        <div v-for="(item, index) in formAddItemList" :key="index">
          <el-col :span="item.colSpan ? item.colSpan : colSpan">
            <el-form-item
              v-if="
                item.type == 'map' &&
                (addtype != 'query' ||
                  (addtype == 'query' && !detail_data[item.key]))
              "
              :label="item.label"
              :label-width="item.labelWidth ? item.labelWidth : labelWidth"
              :required="requiredArr.includes(item.key)"
            >
              <el-button
                type="primary"
                size="small"
                @click="openMap(item.key)"
                :disabled="addtype == 'query'"
              >
                请选择位置
              </el-button>
              {{ detail_data[item.key + "_mapData"].poiname }}
            </el-form-item>
            <el-form-item
              v-if="
                item.type == 'map' &&
                addtype == 'query' &&
                detail_data[item.key]
              "
              :label="item.label"
              :label-width="item.labelWidth ? item.labelWidth : labelWidth"
              :required="requiredArr.includes(item.key)"
            >
              <div class="address-map-div" :id="item.key + '_map'"></div>
            </el-form-item>
            <el-form-item
              v-if="item.type == 'select'"
              :label="item.label"
              :label-width="item.labelWidth ? item.labelWidth : labelWidth"
              :required="requiredArr.includes(item.key)"
            >
              <el-select
                v-model="detail_data[item.key]"
                @change="updateFormObject(item.key)"
                :disabled="addtype == 'query' || item.isDisable"
                :clearable="item.clearable"
                :placeholder="item.placeholder || '请选择'"
                style="width: 100%"
              >
                <el-option
                  v-for="(opt, ind) in detail_data[item.key + '_list']"
                  :key="opt.id"
                  :label="opt.name"
                  :value="opt.id"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item
              v-if="item.type == 'cascader'"
              :label="item.label"
              :label-width="item.labelWidth ? item.labelWidth : labelWidth"
              :required="requiredArr.includes(item.key)"
            >
              <el-cascader
                ref="start"
                :options="detail_data[item.key + '_list']"
                :props="props"
                :disabled="addtype == 'query' || item.isDisable"
                :clearable="item.clearable"
                filterable
                :show-all-levels="true"
                v-model="detail_data[item.key]"
                @change="updateFormObject(item.key)"
                :placeholder="item.placeholder || '请选择'"
              >
              </el-cascader>
            </el-form-item>
            <el-form-item
              v-if="item.type == 'date'"
              :label="item.label"
              :label-width="item.labelWidth ? item.labelWidth : labelWidth"
              :required="requiredArr.includes(item.key)"
            >
              <el-date-picker
                :type="item.type"
                :placeholder="item.placeholder"
                style="width: 100%"
                v-model="detail_data[item.key]"
                :disabled="addtype == 'query' || item.isDisable"
                :picker-options="
                  item.datePickerOptions
                    ? item.datePickerOptions
                    : datePickerOptions
                "
                @change="changeDatetime(item.key)"
              ></el-date-picker>
            </el-form-item>
            <el-form-item
              v-if="item.type == 'daterange'"
              :label="item.label"
              :label-width="item.labelWidth ? item.labelWidth : labelWidth"
              :required="requiredArr.includes(item.key)"
            >
              <el-date-picker
                :type="item.type"
                :placeholder="item.placeholder"
                style="width: 100%"
                v-model="detail_data[item.key]"
                :disabled="addtype == 'query' || item.isDisable"
                :picker-options="
                  item.datePickerOptions
                    ? item.datePickerOptions
                    : datePickerOptions
                "
                @change="changeDateRange(item.key)"
                range-separator="至"
                :default-value="timeDefaultShow"
                :start-placeholder="item.start_placeholder || '开始日期'"
                :end-placeholder="item.end_placeholder || '结束日期'"
              ></el-date-picker>
            </el-form-item>
            <el-form-item
              v-if="item.type == 'string' || item.type == 'number'"
              :label="item.label"
              :label-width="item.labelWidth ? item.labelWidth : labelWidth"
              :required="requiredArr.includes(item.key)"
            >
              <el-input
                v-model="detail_data[item.key]"
                :placeholder="item.placeholder"
                clearable
                type="string"
                @input="item.type=='number'?checkFormatNumFixed2(item):null"
                @blur="item.type=='number'?tt(item.key):null"
                @mousewheel.native.prevent
                @DOMMouseScroll.native.prevent
                :disabled="addtype == 'query' || item.isDisable"
                @change="updateFormObject(item.key)"
              ></el-input>
              <!--:type="item.type"-->
            </el-form-item>
            <el-form-item
              v-if="item.type == 'phone'"
              :label="item.label"
              :label-width="item.labelWidth ? item.labelWidth : labelWidth"
              :required="requiredArr.includes(item.key)"
            >
              <el-input
                v-model="detail_data[item.key]"
                @blur="verifyPhoneFormat(item.key)"
                :placeholder="item.placeholder"
                :disabled="addtype == 'query' || item.isDisable"
                @change="updateFormObject(item.key)"
              ></el-input>
            </el-form-item>
            <el-form-item
              v-if="item.type == 'mail'"
              :label="item.label"
              :label-width="item.labelWidth ? item.labelWidth : labelWidth"
              :required="requiredArr.includes(item.key)"
            >
              <el-input
                v-model="detail_data[item.key]"
                @blur="verifyEmailFormat(item.key)"
                :placeholder="item.placeholder"
                :disabled="addtype == 'query' || item.isDisable"
                @change="updateFormObject(item.key)"
              ></el-input>
            </el-form-item>
            <el-form-item
              v-if="item.type == 'textarea'"
              :label="item.label"
              :label-width="item.labelWidth ? item.labelWidth : labelWidth"
              :required="requiredArr.includes(item.key)"
            >
              <el-input
                v-model="detail_data[item.key]"
                :placeholder="item.placeholder"
                :type="item.type"
                :disabled="addtype == 'query' || item.isDisable"
                @change="updateFormObject(item.key)"
              ></el-input>
            </el-form-item>
            <!--            <el-form-item
                          v-if="item.type == 'editor'"
                          label="内容"
                          :label-width="item.labelWidth ? item.labelWidth : labelWidth"
                          :required="requiredArr.includes(item.key)"
                        >
                          <Editor
                            v-model="detail_data[item.key]"
                            :is-disable="addtype == 'query' || item.isDisable"
                            @input="updateFormObject(item.key)"
                          />
                        </el-form-item>-->
            <el-form-item
              v-if="item.type == 'switch'"
              :label="item.label"
              :label-width="item.labelWidth ? item.labelWidth : labelWidth"
              style="line-height: 36px !important"
              :required="requiredArr.includes(item.key)"
            >
              <el-switch
                v-model="detail_data[item.key]"
                :disabled="addtype == 'query' || item.isDisable"
                @change="updateFormObject(item.key)"
              ></el-switch>
            </el-form-item>
            <el-form-item
              v-if="item.type == 'image'"
              :label="item.label"
              :label-width="item.labelWidth ? item.labelWidth : labelWidth"
              :required="requiredArr.includes(item.key)"
            >
              <upload-safe
                :ref-name="item.key + '_fileUpload'"
                :data-obj="uploadData"
                :file-key="item"
                :file-list="detail_data[item.key + '_files']"
                :is-disabled="addtype == 'query' || item.isDisable"
                accept-format=".png,.jpg,.jpeg"
                :format-type-list="imgFormatTypeList"
                :limit-number="item.maxLength || 999"
                @updateFileList="changeUploadFile"
              ></upload-safe>
              <div>
                <image-cover-preview
                  v-for="(img, ii) in detail_data[item.key + '_file_urls']"
                  :key="ii"
                  v-if="img != '' && img != null"
                  :imgUrl="img"
                ></image-cover-preview>
              </div>
            </el-form-item>
            <el-form-item
              v-if="item.type == 'file'"
              :label="item.label"
              :label-width="item.labelWidth ? item.labelWidth : labelWidth"
              :required="requiredArr.includes(item.key)"
            >
              <upload-safe
                :ref-name="item.key + '_fileUpload'"
                :data-obj="uploadData"
                :file-key="item"
                :file-list="detail_data[item.key + '_files']"
                :is-disabled="addtype == 'query' || item.isDisable"
                :limit-number="item.maxLength || 999"
                @updateFileList="changeUploadFile"
              ></upload-safe>
            </el-form-item>
            <el-form-item
              v-if="item.type == 'pdf'"
              :label="item.label"
              :label-width="item.labelWidth ? item.labelWidth : labelWidth"
              :required="requiredArr.includes(item.key)"
            >
              <upload-safe
                :ref-name="item.key + '_fileUpload'"
                :data-obj="uploadData"
                :file-key="item"
                :file-list="detail_data[item.key + '_files']"
                :is-disabled="addtype == 'query' || item.isDisable"
                accept-format=".pdf"
                :format-type-list="is_UploadTypeList"
                :limit-number="item.maxLength || 999"
                @updateFileList="changeUploadFile"
              ></upload-safe>
            </el-form-item>
          </el-col>
        </div>
      </el-row>
    </el-form>
    <el-dialog
      title="选择位置"
      :visible.sync="dialogVisible"
      :modal-append-to-body="false"
      :destroy-on-close="true"
      center
    >
      <iframe
        id="mapPage"
        width="100%"
        height="520px"
        frameborder="0"
        :src="map_src"
      >
      </iframe>
      <span slot="footer">
        <el-button @click="closeMap">取 消</el-button>
        <el-button type="primary" @click="submitMap">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import {Message} from "element-ui";
import Utils from "@/utils/common";
import ImageCoverPreview
  from "@/pages/admin/components/image-cover-preview.vue";
import UploadSafe from "@/pages/admin/components/upload-safe.vue";
// import Editor from "@/components/Editor/index";
// import {fileUpload} from "@/api/zhjz/upload";

/**
 * formCommonList 动态添加form表单的组件
 * @description 图片默认处理，主要是处理图片加载失败后，显示为给定的默认图片
 * @tutorial
 * @property {Number} colSpan 整体表单单列还是多列显示，默认24 单行显示，单个字段配置的colSpan值优先
 * @property {String} labelWidth 整体表单label的宽度，默认150px
 * @property {String} from 来自哪个页面
 * @property {String} formAddType = [add|update|query] 表单当前所处状态
 *  @value add 添加
 *  @value update 更新
 *  @value query 详情，不可修改
 * @property {Array} formItemList 表单中所有字段列表
 *  @value {}.key 字段值
 *  @value {}.label 字段label名称
 *  @value {}.type = [string|select|number|map|textarea|image|editor|cascader多选] 字段类型
 *  @value {}.placeholder 字段输入框提示语，默认空
 *  @value {}.isDisable 输入框是否禁用
 *  @value {}.colSpan 字段占布局的比例值
 *  @value {}.?(key)_list 为字段类型为select/cascader多选时的被选择列表
 *  @value {}.?(key)_mapData 为字段类型为map时，被选择的位置mapData对象
 *  @value {}.?(key)_files 为字段类型为files时，选择的文件列表
 *  @value {}.?(key)_file_ids 为字段类型为file_ids时，选择的文件列表id数组
 *  @value {}.?(key)_file_urls 为字段类型为file_ids时，选择的文件列表id数组
 * @property {Object} formObject 表单各字段对应的值所在的父级对象
 * @event {Function} changeFormObject 当修改form表单任意一项，更新父级表单的整体数据 params
 * @example
 */
// * @property {Boolean} draggable = [true|false] 是否能拖动图片
// * @event {Function} changeAddressSelected 当选择地图后修改，提示更新了那个key对应的地图选择数据 key/address/lng/lat
// * @event {Function} changeFileImgList 当选择图片后修改，提示更新了那个key对应的地图选择数据 key/files/file_ids
// * @event {Function} changeFileList 当选择文本附件后修改，提示更新了那个key对应的地图选择数据 key/files/file_ids

export default {
  name: "formCommonList",
  components: {
    ImageCoverPreview,
    UploadSafe,
  },
  props: {
    labelPosition: {
      type: String,
      default() {
        return "right";
      },
    },
    colSpan: {
      type: Number,
      default() {
        return 24;
      },
    },
    labelWidth: {
      type: String,
      default() {
        return "150px";
      },
    },
    from: {
      type: String,
      default() {
        return "";
      },
    },
    formAddType: {
      type: String,
      default() {
        return "add";
      },
    },
    formItemList: {
      type: Array,
      default() {
        return [];
      },
    },
    formObject: {
      type: Object,
      default() {
        return {};
      },
    },
    requiredArr: {
      type: Array,
      default() {
        return [];
      },
    },
  },
  watch: {
    formAddType: {
      handler(val, oldVal) {
        if (val) {
          this.addtype = val;
        }
      },
      immediate: true,
      deep: true,
    },
    formItemList: {
      handler(val, oldVal) {
        if (val) {
          this.formAddItemList = val;
        }
      },
      immediate: true,
      deep: true,
    },
    formObject: {
      handler(val, oldVal) {
        if (val) {
          this.detail_data = val;
        }
      },
      immediate: true,
      deep: true,
    },
  },
  data() {
    return {
      addtype: "add",
      formAddItemList: [],
      detail_data: {},
      props: {
        multiple: false,
        checkStrictly: false,
        value: "id",
        label: "name",
      },
      // 地址
      map_src: "",
      dialogVisible: false,
      mapKey: "",
      // 日期选择控件
      datePickerOptions: {
        disabledDate(time) {
          return time.getTime() > Date.now();
        },
      },
      // 上传图片
      curFileObj: {}, // 上传至哪一个图片/附件字段的item
      uploadData: {},
      imgFormatTypeList: ["image/jpeg", "image/png", "image/jpg"],
      timeDefaultShow: new Date(),

      is_UploadTypeList: ["application/pdf"], //pdf上传类型
    };
  },
  created() {
    this.timeDefaultShow.setMonth(new Date().getMonth() - 1);
    // 腾讯地图
    window.addEventListener(
      "message",
      (event) => {
        // 接收位置信息，用户选择确认位置点后选点组件会触发该事件，回传用户的位置信息
        let loc = event.data;
        if (loc && loc.module == "locationPicker") {
          for (let i = 0; i < this.formAddItemList.length; i++) {
            let tp = this.formAddItemList[i];
            if (tp.type == "map") {
              this.detail_data[tp.key + "_mapData"].address = loc.poiaddress;
              this.detail_data[tp.key + "_mapData"].lat = loc.latlng.lat;
              this.detail_data[tp.key + "_mapData"].lng = loc.latlng.lng;
              this.detail_data[tp.key + "_mapData"].poiname = loc.poiname;
            }
          }
        }
      },
      false
    );
    if (this.addtype == "add") {
      this.map_src =
        "https://apis.map.qq.com/tools/locpicker?search=1&type=1&key=CYQBZ-VGPK4-7JKUQ-XPE3E-SSN3H-EXFVJ&referer=myapp name&coord=35.937224,116.47024";
    }
  },
  mounted() {
  },
  methods: {
    updateFormObject(key) {
      this.$emit("changeFormObject", {
        keys: [key],
        data: this.detail_data,
      });
    },
    checkFormatNumFixed2(item) {
      this.detail_data[item.key] = Utils.checkNumber(
        this.detail_data[item.key] + "");
      if (item.verifyOptions && item.verifyOptions.isPositive) {
        this.detail_data[item.key] = this.detail_data[item.key].replace(/\-/g, "");
      }
    },
    tt(key_str) {
      if (this.detail_data[key_str] != "") {
        this.detail_data[key_str] = parseFloat(this.detail_data[key_str]);
      }
    },
    verifyPhoneFormat(key) {
      if (!/^1[3-9]\d{9}$/.test(this.detail_data[key])) {
        // Message.warning("手机号格式不正确");
        return;
      }
    },
    verifyEmailFormat(key) {
      if (
        !/^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(this.detail_data[key])
      ) {
        // Message.warning("邮箱格式不正确");
        return;
      }
    },
    //地图选点确定
    submitMap() {
      if (
        this.detail_data[this.mapKey + "_mapData"].lat === "" ||
        this.detail_data[this.mapKey + "_mapData"].lng === ""
      ) {
        Message.warning("请先选择地址！");
        return;
      }
      this.detail_data[this.mapKey] = JSON.stringify(
        this.detail_data[this.mapKey + "_mapData"]
      );
      // this.detail_data.lng = this.map_data.lng;
      // this.detail_data.lat = this.map_data.lat;
      this.$emit("changeFormObject", {
        keys: [this.mapKey, this.mapKey + "_mapData"],
        data: this.detail_data,
      });
      this.dialogVisible = false;
    },
    openMap(key) {
      this.mapKey = key;
      this.dialogVisible = true;
    },
    closeMap() {
      this.mapKey = "";
      this.dialogVisible = false;
    },
    changeUploadFile(params) {
      // fileKey: this.fileKey,
      //   file: file,
      //   fileList: fileList,
      // console.log('change upload files=====',JSON.stringify(params))
      this.curFileObj = params.fileKey || {key: "upload"};
      let fileList = params.fileList || [];
      // this.detail_data[this.curFileObj.key + '_files'] = fileList;
      this.$set(this.detail_data, this.curFileObj.key + "_files", fileList);
      let ids = [],
        urls = [];
      for (let i = 0; i < fileList.length; i++) {
        ids.push(fileList[i].id);
        urls.push(fileList[i].url);
      }
      // this.detail_data[this.curFileObj.key + '_file_ids'] = ids;
      // this.detail_data[this.curFileObj.key + '_file_urls'] = urls;
      this.$set(this.detail_data, this.curFileObj.key + "_file_ids", ids);
      this.$set(this.detail_data, this.curFileObj.key + "_file_urls", urls);
      this.$emit("changeFormObject", {
        keys: [
          this.curFileObj.key,
          this.curFileObj.key + "_files",
          this.curFileObj.key + "_file_ids",
          this.curFileObj.key + "_file_urls",
        ],
        data: this.detail_data,
      });
    },
    changeDatetime(item) {
      let datetime = JSON.parse(JSON.stringify(this.detail_data[item]));
      let y = this.handleDate(new Date(datetime).getFullYear());
      let m = this.handleDate(new Date(datetime).getMonth() + 1);
      let d = this.handleDate(new Date(datetime).getDate());
      // var h = this.handleDate(new Date(datetime).getHours())
      // var mm =this.handleDate(new Date(datetime).getMinutes())
      // var s = this.handleDate(new Date(datetime).getSeconds())
      let newdate = y + "-" + m + "-" + d;
      this.detail_data[item] = JSON.parse(JSON.stringify(newdate));

      this.$emit("changeFormObject", {
        keys: [item],
        data: this.detail_data,
      });
    },
    changeDateRange(item) {
      let datetime = JSON.parse(JSON.stringify(this.detail_data[item]));
      if (datetime == null) {
        this.detail_data[item] = [];
      } else {
        let startTime = datetime && datetime[0];
        let endtTime = datetime && datetime[1];
        // console.log(datetime, startTime, endtTime)
        let y = this.handleDate(new Date(startTime).getFullYear());
        let m = this.handleDate(new Date(startTime).getMonth() + 1);
        let d = this.handleDate(new Date(startTime).getDate());
        // var h = this.handleDate(new Date(datetime).getHours())
        // var mm =this.handleDate(new Date(datetime).getMinutes())
        // var s = this.handleDate(new Date(datetime).getSeconds())
        let newdate_start = y + "-" + m + "-" + d;
        // console.log(newdate_start)
        let y_end = this.handleDate(new Date(endtTime).getFullYear());
        let m_end = this.handleDate(new Date(endtTime).getMonth() + 1);
        let d_end = this.handleDate(new Date(endtTime).getDate());
        // var h_end = this.handleDate(new Date(endtTime).getHours())
        // var mm_end =this.handleDate(new Date(endtTime).getMinutes())
        // var s_end = this.handleDate(new Date(endtTime).getSeconds())
        let newdate_end = y_end + "-" + m_end + "-" + d_end;
        this.detail_data[item] = [
          JSON.parse(JSON.stringify(newdate_start)),
          JSON.parse(JSON.stringify(newdate_end)),
        ];
      }
      this.$emit("changeFormObject", {
        keys: [item],
        data: this.detail_data,
      });
    },
    handleDate(item) {
      var tt = "";
      if (item < 10) {
        tt = "0" + item;
        return tt;
      } else {
        tt = item;
        return tt;
      }
    },
  },
};
</script>

<style scoped></style>
